#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <signal.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <glib.h>
#include <gdk/gdkkeysyms.h>

#include "read.h"
#include "theme.h"
#include "pref.h"
#include "optionwnd.h"

#define MENU_HEIGHT 24
#define TOOL_HEIGHT 32
#define VERSION "0.1"

READER* reader;
READER_FRAME* frame;

static void app_init() {
	frame = g_malloc(sizeof(READER_FRAME));
	frame->play_icon = NULL;
	frame->pause_icon = NULL;
//	frame->timer = NULL;

	reader = g_malloc(sizeof(READER));
	reader->step = 3;
	reader->scrolling = FALSE;
	reader->fn[0] = '\0';
	strncpy(reader->charset, "GBK", 10);
	strncpy(reader->font, "Monospace Bold 10",40);
	strncpy(reader->theme, "Basic",20);
}

static void on_destroy(GtkWidget *widget, gpointer data) {
	gtk_main_quit();
}

static void on_about(GtkWidget* menu_item, gpointer data) {
	static const char* authors[] = { "Xiaodong Jiang" };
	gtk_show_about_dialog(GTK_WINDOW(frame->window), "program-name",
			"JReader", "version", "0.1", "copyright",
			"Copyright Xiaodong Jiang(jxd431@hotmail.com)", "authors", authors,
			NULL);
}

static void font_dialog_response(GtkFontSelectionDialog *dialog, gint response,
		gpointer data) {
	gchar *font;
	GtkWidget *message;
	switch (response) {
	case (GTK_RESPONSE_APPLY):
	case (GTK_RESPONSE_OK):
		font = gtk_font_selection_dialog_get_font_name(dialog);
		reader_update_font(font);
		g_free(font);
		break;
	default:
		gtk_widget_destroy(GTK_WIDGET(dialog));
	}
	if (response == GTK_RESPONSE_OK)
		gtk_widget_destroy(GTK_WIDGET(dialog));
}

void on_scroll(int signum) {
	GtkRange* bar = GTK_RANGE(gtk_scrolled_window_get_vscrollbar(frame->scroll));
	double y = gtk_range_get_value(bar);
	y += reader->step;
	gtk_range_set_value(bar, y);
}

static void on_play() {
	struct itimerval timer;
	timer.it_interval.tv_sec = 0;
	timer.it_interval.tv_usec = 100000;
	timer.it_value.tv_sec = 0;
	timer.it_value.tv_usec = 100000;
	int ret = 0;
	if ((ret = setitimer(ITIMER_REAL, &timer, NULL)) != 0) {
		fprintf(stderr, "set timer error\n");
		return;
	} 
	if (signal(SIGALRM, on_scroll) == SIG_ERR) {
		fprintf(stderr, "error to create signal\n");
		return;
	}
	gtk_widget_set_sensitive(GTK_WIDGET(frame->play_icon),FALSE);
	gtk_widget_set_sensitive(GTK_WIDGET(frame->pause_icon),TRUE);
	reader->scrolling = TRUE;
}

static void on_pause(GtkWidget* widget, gpointer data) {
	struct itimerval timer;
	getitimer(ITIMER_REAL, &timer);
	timer.it_value.tv_sec = 0;
	timer.it_value.tv_usec = 0;
	setitimer(ITIMER_REAL, &timer, NULL);
	gtk_widget_set_sensitive(GTK_WIDGET(frame->play_icon),TRUE);
	gtk_widget_set_sensitive(GTK_WIDGET(frame->pause_icon),FALSE);
	reader->scrolling = FALSE;
}

static void on_key_press(GtkWidget* widget, GdkEventKey *event, gpointer data) {
	if (event->keyval != GDK_Return) return;
	if (reader->scrolling) {
		on_pause(NULL,NULL);
	}
	else {
		on_play(NULL,NULL);
	}
}

static void on_font_open(GtkWidget* menu_item, gpointer data) {
	GtkWidget* dlg = gtk_font_selection_dialog_new("Select Font");
	gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(dlg),
			reader->font);
	gtk_font_selection_dialog_set_preview_text (GTK_FONT_SELECTION_DIALOG (dlg),
	                                              "jReader by Xiaodong Jiang");
	g_signal_connect (G_OBJECT (dlg), "response",
			G_CALLBACK (font_dialog_response), NULL);
	gtk_dialog_run(GTK_DIALOG(dlg));
}

static void on_options_open(GtkWidget* menu_item, gpointer data) {
	GtkDialog* dlg = option_dlg_open();
}

static void on_file_open(GtkWidget* menu_item, gpointer data) {
	GtkWidget* dialog = gtk_file_chooser_dialog_new("Select File",
			(GtkWindow*)frame->window, GTK_FILE_CHOOSER_ACTION_OPEN,
			GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN,
			GTK_RESPONSE_ACCEPT, NULL);
	if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
		char *filename;

		filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
		reader_load(filename);
		//open_file (filename);
		g_free(filename);
	}

	gtk_widget_destroy(dialog);

}

static void on_file_close(GtkWidget* menu_item, gpointer data) {
	reader_close();
	on_pause(NULL,NULL);
}

static void on_charset_changed(GtkComboBox *combo, gpointer user_data) {
	gchar* charset = gtk_combo_box_get_active_text(combo);
	strncpy(reader->charset,charset,10);
	reader_reload();
}

//
//GtkWidget* about_dialog_setup() {
//	GtkWidget* dlg = gtk_about_dialog_new();
//	gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(dlg), "RReadbook");
//	gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dlg), "0.1");
//	gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(dlg),
//			"http://book.andrewkrause.net");
//	return dlg;
//}

void frame_setup() {
	frame->window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
	gtk_window_set_title(GTK_WINDOW(frame->window), "JReader");
	gtk_container_set_border_width(GTK_CONTAINER(frame->window), 0);
	gtk_widget_set_size_request(GTK_WIDGET(frame->window), 640, 480);
	g_signal_connect(G_OBJECT(frame->window), "destroy",
			G_CALLBACK(on_destroy), NULL);
}

GtkWidget* menubar_setup() {
	GtkWidget* menubar = gtk_menu_bar_new();
	GtkAccelGroup* group = gtk_accel_group_new();

	GtkWidget* file = gtk_menu_item_new_with_mnemonic("_File");
	GtkWidget* file_menu = gtk_menu_new();
	GtkWidget* open = gtk_image_menu_item_new_from_stock(GTK_STOCK_OPEN, group);
	g_signal_connect(GTK_OBJECT(open), "activate", G_CALLBACK(on_file_open),
			NULL);
	GtkWidget* close = gtk_image_menu_item_new_from_stock(GTK_STOCK_CLOSE, group);
	g_signal_connect(GTK_OBJECT(close), "activate", G_CALLBACK(on_file_close),
			NULL);
	GtkWidget* exit = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, group);
	g_signal_connect(GTK_OBJECT(exit), "activate", G_CALLBACK(on_destroy), NULL);
	gtk_menu_item_set_submenu(GTK_MENU_ITEM(file), file_menu);
	gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), open);
	gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), close);
	gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), exit);

	GtkWidget* view_menu = gtk_menu_new();
	GtkWidget* view = gtk_menu_item_new_with_mnemonic("_View");
	GtkWidget* font = gtk_image_menu_item_new_from_stock(GTK_STOCK_SELECT_FONT,
			group);
	GtkWidget* options = gtk_image_menu_item_new_from_stock(GTK_STOCK_PREFERENCES,
			group);
	gtk_menu_item_set_submenu(GTK_MENU_ITEM(view), view_menu);
	gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), font);
	gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), options);
	g_signal_connect(GTK_OBJECT(font), "activate", G_CALLBACK(on_font_open),
			NULL);
	g_signal_connect(GTK_OBJECT(options), "activate", G_CALLBACK(on_options_open),
			NULL);

	GtkWidget* help_menu = gtk_menu_new();
	GtkWidget* help = gtk_menu_item_new_with_mnemonic("_Help");
	GtkWidget* about = gtk_image_menu_item_new_from_stock(GTK_STOCK_ABOUT,
			group);
	g_signal_connect(GTK_OBJECT(about), "activate", G_CALLBACK(on_about), NULL);
	gtk_menu_item_set_submenu(GTK_MENU_ITEM(help), help_menu);
	gtk_menu_shell_append(GTK_MENU_SHELL(help_menu), about);

	gtk_menu_shell_append(GTK_MENU_SHELL(menubar), file);
	gtk_menu_shell_append(GTK_MENU_SHELL(menubar), view);
	gtk_menu_shell_append(GTK_MENU_SHELL(menubar), help);

	gtk_widget_set_size_request(menubar, -1, MENU_HEIGHT);
	return menubar;
}

GtkWidget* toolbar_setup() {
	GtkToolbar * toolbar = GTK_TOOLBAR(gtk_toolbar_new());
	gtk_toolbar_set_style(toolbar, GTK_TOOLBAR_ICONS);
	GtkTooltips *tips = gtk_tooltips_new ();
	gtk_container_set_border_width(GTK_CONTAINER(toolbar), 0);
	
	GtkToolItem* open = gtk_tool_button_new_from_stock(GTK_STOCK_OPEN);
	gtk_tooltips_set_tip (GTK_TOOLTIPS (tips), GTK_WIDGET(open),
					 "Open a file","Open a file");
	gtk_toolbar_insert(toolbar,open,-1);
	GtkToolItem* close = gtk_tool_button_new_from_stock(GTK_STOCK_CLOSE);
	gtk_tooltips_set_tip (GTK_TOOLTIPS (tips), GTK_WIDGET(close),
					 "Close current file","Close current file");
	gtk_toolbar_insert(toolbar,close,-1);
	

	GtkToolItem* sep = gtk_separator_tool_item_new();
	gtk_toolbar_insert(GTK_TOOLBAR(toolbar), sep, -1);
	
	GtkToolItem* play = gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_PLAY);
	gtk_tooltips_set_tip (GTK_TOOLTIPS (tips), GTK_WIDGET(play),
					 "Play current file","Play current file");
	gtk_toolbar_insert(toolbar,play,-1);
	frame->play_icon = play;

	GtkToolItem* pause = gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_PAUSE);
	gtk_tooltips_set_tip (GTK_TOOLTIPS (tips), GTK_WIDGET(pause),
					 "Pause to playing","Pause to playing");
	gtk_widget_set_sensitive(GTK_WIDGET(pause),FALSE);
	gtk_toolbar_insert(toolbar,pause,-1);
	frame->pause_icon = pause;
	
	// build charset combo box
	GtkListStore* model = GTK_LIST_STORE(gtk_list_store_new(1,G_TYPE_STRING));
	GtkTreeIter iter;
	gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model),&iter);
	gtk_list_store_append(model,&iter);
	gtk_list_store_set(model,&iter,0,"GBK",-1);
	gtk_list_store_append(model,&iter);
	gtk_list_store_set(model,&iter,0,"UTF-8",-1);
	GtkComboBox* combo = GTK_COMBO_BOX(gtk_combo_box_new_with_model(GTK_TREE_MODEL(model)));
	g_object_unref(model);
	GtkCellRenderer *cell = gtk_cell_renderer_text_new();
	gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), cell, TRUE);
	gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), cell, "text", 0, NULL);
	
	gtk_combo_box_set_title(GTK_COMBO_BOX(combo),"Charset");
	gtk_combo_box_set_active(GTK_COMBO_BOX(combo),0);
	GtkToolItem* cont = gtk_tool_item_new();
	gtk_container_add(GTK_CONTAINER(cont),GTK_WIDGET(combo));
	gtk_toolbar_insert(toolbar,cont,-1);
	
	g_signal_connect (G_OBJECT (open), "clicked",
			G_CALLBACK (on_file_open), NULL);
	g_signal_connect (G_OBJECT (close), "clicked",
			G_CALLBACK (on_file_close), NULL);
	g_signal_connect (G_OBJECT (play), "clicked",
			G_CALLBACK (on_play), NULL);
	g_signal_connect (G_OBJECT (pause), "clicked",
			G_CALLBACK (on_pause), NULL);
	g_signal_connect (G_OBJECT (combo), "changed",
			G_CALLBACK (on_charset_changed), NULL);
	return GTK_WIDGET(toolbar);
}

GtkWidget* view_setup() {
	frame->scroll = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL));
	frame->view = GTK_TEXT_VIEW(gtk_text_view_new());
	gtk_text_view_set_left_margin(frame->view, 10);
	gtk_text_view_set_right_margin(frame->view, 10);
	gtk_text_view_set_editable(frame->view, FALSE);
	gtk_text_view_set_cursor_visible(frame->view, FALSE);
	gtk_text_view_set_wrap_mode(frame->view, GTK_WRAP_WORD) ;
	gtk_container_add(GTK_CONTAINER(frame->scroll ),GTK_WIDGET(frame->view));
//	gtk_widget_set_size_request(GTK_WIDGET(frame->view), 300, 200);
	gtk_scrolled_window_set_policy(frame->scroll,
			GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
	g_signal_connect (G_OBJECT (frame->view), "key-press-event",
			G_CALLBACK (on_key_press), NULL);
}

void refresh_size(GtkWidget* menubar, GtkWidget* toolbar) {
	GdkScreen* screen = gtk_widget_get_screen(GTK_WIDGET(frame->window));
	gint width = gdk_screen_get_width(screen);
	gtk_widget_set_size_request(menubar, width, MENU_HEIGHT);
	gtk_widget_set_size_request(toolbar, width, TOOL_HEIGHT);
	gtk_widget_set_size_request(GTK_WIDGET(frame->scroll), width, 400);
}

int main(int argc, char** argv) {
	GtkWidget *menubar, *toolbar, *layout;
	gtk_init(&argc, &argv);
	g_type_init();
	app_init();

	frame_setup();
	layout = gtk_vbox_new(FALSE, 0);
	menubar = menubar_setup();
	toolbar = toolbar_setup();
	view_setup();

	gtk_container_add(GTK_CONTAINER(frame->window), layout);
	gtk_box_pack_start(GTK_BOX(layout), menubar, FALSE, FALSE, 0);
	gtk_box_pack_start(GTK_BOX(layout), toolbar, FALSE, FALSE, 0);

	refresh_size(menubar, toolbar);
	gtk_box_pack_start(GTK_BOX(layout), GTK_WIDGET(frame->scroll), TRUE, TRUE, 0);

	theme_init();
	pref_load();

	if (strcmp(reader->fn,"")) {
		reader_load(reader->fn);
	}
	
	gtk_window_set_position(GTK_WINDOW(frame->window), GTK_WIN_POS_CENTER);
	gtk_widget_show_all(GTK_WIDGET(frame->window));
	gtk_main();


	pref_save();
}
